﻿using Rhino.Display;
using Rhino.DocObjects;
using Rhino.Geometry;
using System;
using System.Drawing;

namespace AiMoInGH.ScriptInstance.Preview
{
    class PreviewGeometryBase : PreviewObject
    {
        readonly Mesh[] previewMesh;
        readonly DisplayMaterial material;
        readonly bool m_DrawMeshVerticesColor = false;
        public PreviewGeometryBase(GeometryBase geo, Color color) : base(color)
        {
            material = new DisplayMaterial(color, 1 - color.A / 255.0);
            switch (geo)
            {
                case Mesh mesh:
                    previewMesh = new Mesh[] { mesh.DuplicateMesh() };
                    m_DrawMeshVerticesColor = mesh.VertexColors.Count > 0;
                    break;
                case Extrusion extrusion:
                    previewMesh = Mesh.CreateFromBrep(extrusion.ToBrep(), MeshingParameters.FastRenderMesh);
                    break;
                case Brep brep:
                    previewMesh = Mesh.CreateFromBrep(brep, MeshingParameters.FastRenderMesh);
                    break;
                case Surface surface:
                    previewMesh = new Mesh[] { Mesh.CreateFromSurface(surface, MeshingParameters.FastRenderMesh) };
                    break;
                default:
                    previewMesh = Array.Empty<Mesh>();
                    break;
            }
            if (previewMesh != null)
            {
                foreach (Mesh mesh in previewMesh)
                {
                    if (mesh.FaceNormals.Count == 0 || mesh.Normals.Count == 0)
                    {
                        mesh.RebuildNormals();
                        mesh.FaceNormals.ComputeFaceNormals();
                    }
                }
            }
            ClippingBox = geo.GetBoundingBox(false);
        }
        public override void Draw(DisplayPipeline display)
        {
            if (m_DrawMeshVerticesColor)
            {
                foreach (Mesh mesh in previewMesh)
                {
                    display.DrawMeshFalseColors(mesh);
                }
            }
            else
            {
                foreach (Mesh mesh in previewMesh)
                {
                    display.DrawMeshShaded(mesh, material);
                }
            }

        }
    }

    class PreviewAnnotationBase : PreviewObject
    {
        readonly AnnotationBase annotationBase;
        public PreviewAnnotationBase(AnnotationBase annotationBase, Color color) : base(color)
        {
            this.annotationBase = annotationBase.Duplicate() as AnnotationBase;

            ClippingBox = annotationBase.GetBoundingBox(false);
        }
        public override void Draw(DisplayPipeline display)
        {
            display.DrawAnnotation(annotationBase, DrawColor);
        }
    }


    class PreviewRhinoObject : PreviewObject
    {
        readonly RhinoObject rhinoObject;
        public PreviewRhinoObject(RhinoObject rhinoObject, Color color) : base(color)
        {
            this.rhinoObject = rhinoObject;
            ClippingBox = rhinoObject.Geometry.GetBoundingBox(false);
        }
        public override void Draw(DisplayPipeline display)
        {
            display.DrawObject(rhinoObject);
        }
    }


    class PreviewTextDot : PreviewObject
    {
        readonly TextDot textDot;
        public PreviewTextDot(TextDot text, Color color) : base(color)
        {
            textDot = text.Duplicate() as TextDot;
            ClippingBox = text.GetBoundingBox(false);
        }
        public override void Draw(DisplayPipeline display)
        {
            display.Draw2dText(textDot.Text, DrawColor, textDot.Point, true, textDot.FontHeight, textDot.FontFace);
        }
    }


    class PreviewHatch : PreviewObject
    {
        readonly Hatch geo;
        public PreviewHatch(Hatch geo, Color color) : base(color)
        {
            this.geo = geo.Duplicate() as Hatch;
            ClippingBox = geo.GetBoundingBox(false);
        }
        public override void Draw(DisplayPipeline display)
        {
            display.DrawHatch(geo, DrawColor, DrawColor);
        }
    }

    class PreviewText3d : PreviewObject
    {
        readonly Text3d text3d;
        public PreviewText3d(Text3d text3d, Color color) : base(color)
        {
            this.text3d = text3d;
            ClippingBox = text3d.BoundingBox;
        }
        public override void Draw(DisplayPipeline display)
        {
            display.Draw3dText(text3d, DrawColor);
        }
    }

    class PreviewCurve : PreviewObject
    {
        readonly Curve geo;
        public PreviewCurve(Curve geo, Color color) : base(color)
        {
            this.geo = geo.DuplicateCurve();
            ClippingBox = geo.GetBoundingBox(false);
        }
        public override void Draw(DisplayPipeline display)
        {
            display.DrawCurve(geo, DrawColor);
        }
    }
    class DrawPolyline : PreviewObject
    {
        readonly Polyline geo;
        public DrawPolyline(Polyline geo, Color color) : base(color)
        {
            this.geo = geo.Duplicate();
            ClippingBox = geo.BoundingBox;
        }
        public override void Draw(DisplayPipeline display)
        {
            display.DrawPolyline(geo, DrawColor);
        }
    }
}
